home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
misc
/
pdflib
/
p_filter.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-01
|
4KB
|
168 lines
/* p_filter.c
* Copyright (C) 1997-98 Thomas Merz. All rights reserved.
*
* ASCII85 and Hex encoding for PDFlib
*/
#include <stdio.h>
#include <fcntl.h>
#include "p_intern.h"
#ifdef DOS
#include <io.h>
#include <stdlib.h>
#endif
static const unsigned long power85[5] =
{ 1L, 85L, 85L*85, 85L*85*85, 85L*85*85*85};
/* Auxiliary routines */
/* output one ASCII byte and keep track of characters per line */
static void
pdf_outbyte(PDF *p, byte c)
{
if (fputc(c, p->fp) == EOF)
pdf_error(p, PDF_FATAL, "Write error in pdf_outbyte()");
#define MAX_CHARS_PER_LINE 64
/* insert line feed */
if (++(p->chars_on_this_line) == MAX_CHARS_PER_LINE)
{
fputc('\n', p->fp);
p->chars_on_this_line = 0;
}
}
void
pdf_ASCII85Encode(PDF *p, PDF_data_source *src)
{
unsigned long word, v;
int i, fetched;
byte buf[4];
src->init(p, src);
if (!src->fill(p, src)) {
pdf_error(p, PDF_WARN, "Data underrun in pdf_ASCII85Encode");
fputs("~>\n", p->fp); /* EOD marker */
return;
}
p->chars_on_this_line = 0;
while (1)
{
for (fetched = 0; fetched < 4; fetched++)
{
if (src->bytes_available == 0 && !src->fill(p, src))
break;
buf[fetched] = *(src->next_byte);
src->next_byte++;
src->bytes_available--;
}
if (fetched < 4)
break;
/* 4 bytes available ==> output 5 bytes */
word = ((unsigned long)(((unsigned int)buf[0] << 8) + buf[1]) << 16) +
(((unsigned int)buf[2] << 8) + buf[3]);
if (word == 0)
pdf_outbyte(p, (byte) 'z'); /* shortcut for 0 */
else
{
/* calculate 5 ASCII85 bytes and output them */
for (i = 4; i >= 0; i--) {
v = word / power85[i];
pdf_outbyte(p, (byte)v + '!');
word -= v * power85[i];
}
}
}
word = 0;
/* 0-3 bytes left */
if (fetched != 0)
{
for (i = fetched - 1; i >= 0; i--) /* accumulate bytes */
word += (unsigned long)buf[i] << 8 * (3-i);
/* encoding as above, but output only fetched+1 bytes */
for (i = 4; i >= 4-fetched; i--)
{
v = word / power85[i];
pdf_outbyte(p, (byte)v + '!');
word -= v * power85[i];
}
}
src->terminate(p, src);
fputs("~>\n", p->fp); /* EOD marker */
}
void
pdf_ASCIIHexEncode(PDF *p, PDF_data_source *src)
{
static const char BinToHex[] = "0123456789ABCDEF";
int CharsPerLine;
long i;
byte *data;
CharsPerLine = 0;
src->init(p, src);
while (src->fill(p, src))
{
for (data=src->next_byte, i=src->bytes_available; i > 0; i--, data++)
{
putc(BinToHex[*data>>4], p->fp); /* first nibble */
putc(BinToHex[*data & 0x0F], p->fp); /* second nibble */
if ((CharsPerLine += 2) >= 64) {
putc('\n', p->fp);
CharsPerLine = 0;
}
}
}
src->terminate(p, src);
(void) fputs(">\n", p->fp); /* EOD marker for PDF hex strings */
}
/* methods for constructing a data source from a memory buffer */
/* dummy for use in PDF_data_source */
static void
pdf_noop(PDF *p, PDF_data_source *src)
{
}
static bool
pdf_data_source_buf_fill(PDF *p, PDF_data_source *src)
{
if (src->next_byte == NULL) {
src->next_byte = src->buffer_start;
src->bytes_available = src->buffer_length;
return true;
}
return false;
}
void
PDF_data_source_from_buf(PDF *p, PDF_data_source *src, byte *buffer, long len)
{
src->init = pdf_noop;
src->fill = pdf_data_source_buf_fill;
src->terminate = pdf_noop;
src->buffer_start = buffer;
src->buffer_length = len;
src->bytes_available= 0;
src->next_byte = NULL;
}